package cz.cvut.kadledav.paa.knapsack.tasks;

import cz.cvut.kadledav.paa.knapsack.bo.Item;

import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

/**
 * User: David Kadlecek
 * Date: 1.11.13
 */
public class FPTAS extends DynamicProgramingByCostTask {

    public static String MAX_RELATIVE_DEVIATION = "max allowed rel deviation";

    private Item[] originalItems;

    @Override
    public void initialize(ArrayList<Item> items, Map<String, Object> params) {
        ArrayList<Item> roundedItems = new ArrayList<>(items.size());
        double epsilon = Double.parseDouble(params.get(MAX_RELATIVE_DEVIATION).toString());
        double cMax = 0;
        for (Item originalItem : items) {
            if(originalItem.getPrice()>cMax){
                cMax = originalItem.getPrice();
            }
        }
        double k = (epsilon * cMax)/(double) items.size();
        originalItems = new Item[items.size()];
        for (int i = 0; i < items.size(); i++) {
            if(items.get(i).getPrice()>cMax){
                cMax = items.get(i).getPrice();
            }
            originalItems[i] = items.get(i);
        }

        for (Item originalItem : items) {
            long newPrice = (long)(originalItem.getPrice() / k);
            if(newPrice > Integer.MAX_VALUE) {
                new RuntimeException("computed price is too big something is wrong : "+newPrice);
            }
            Item item = new Item(originalItem.getId(),originalItem.getWeight(), (int) newPrice);
            roundedItems.add(item);
        }
        setItems(roundedItems);
    }

    @Override
    public void compute() {
        super.compute();
        Set<Integer> computedItemsIds = getComputedItemsIds();
        int solution = 0;
        for (Integer id : computedItemsIds) {
            solution += originalItems[id].getPrice();
        }
        maxPrice = solution;
    }
}
